package com.gqh.weather.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gqh.weather.auth.UserContext;
import com.gqh.weather.domain.dto.*;
import com.gqh.weather.domain.entity.Question;
import com.gqh.weather.domain.enums.TiXingEnum;
import com.gqh.weather.domain.enums.XuekeEnum;
import com.gqh.weather.exception.BusinessException;
import com.gqh.weather.exception.Result;
import com.gqh.weather.mapper.QuestionMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 题目管理服务类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QuestionService extends ServiceImpl<QuestionMapper, Question> {

    private final QuestionMapper questionMapper;

    /**
     * 创建题目
     *
     * @param request 创建请求
     * @return 操作结果
     */
    public Result<Void> createQuestion(QuestionCreateRequest request) {
        try {
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();
            
            // 构建Question实体
            Question question = new Question();
            question.setType(request.getType());
            question.setQtype(request.getQtype());
            question.setTitle(request.getTitle());
            question.setData(request.getData());
            question.setContent(request.getContent());
            question.setAnswer(request.getAnswer());
            question.setPicUrl(request.getPic_url());
            question.setSubid(request.getSubid());
            question.setStype(request.getStype());
            question.setNote(request.getNote());
            question.setDifficulty(request.getDifficulty());
            question.setCreatedBy(currentUserId);
            question.setIfPublish(0); // 默认未发布
            question.setIsDeleted(0); // 默认未删除

            if (question.getQtype() != 100) {
                question.setSubid("[]");
            }

            check(question);

            // 保存到数据库
            boolean saved = this.save(question);
            if (!saved) {
                throw new BusinessException("创建题目失败");
            }

            log.info("题目创建成功, ID: {}, 创建人: {}", question.getId(), currentUserId);
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("创建题目失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("创建题目发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 更新题目
     * MyBatis-Plus的逻辑删除会自动过滤is_deleted=1的数据
     *
     * @param request 更新请求
     * @return 操作结果
     */
    public Result<Void> updateQuestion(QuestionUpdateRequest request) {
        try {
            // 查询题目是否存在（自动过滤已删除数据）
            Question existingQuestion = this.getById(request.getId());
            if (existingQuestion == null) {
                throw new BusinessException("题目不存在");
            }

            // 验证题目是否已发布（已发布题目不可修改）
            // if (existingQuestion.getIfPublish() == 1) {
            //     throw new BusinessException("题目已发布，不可修改");
            // }

            // 复制请求数据到实体对象
            Question question = new Question();
            question.setId(request.getId());
            question.setType(request.getType());
            question.setQtype(request.getQtype());
            question.setTitle(request.getTitle());
            question.setData(request.getData());
            question.setContent(request.getContent());
            question.setAnswer(request.getAnswer());
            question.setPicUrl(request.getPic_url());
            question.setSubid(request.getSubid());
            question.setStype(request.getStype());
            question.setNote(request.getNote());
            question.setDifficulty(request.getDifficulty());

            if (question.getQtype() != 100) {
                question.setSubid("[]");
            }

            check(question);

            // 更新题目
            boolean updated = this.updateById(question);
            if (!updated) {
                throw new BusinessException("更新题目失败");
            }

            log.info("题目更新成功, ID: {}", request.getId());
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("更新题目失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("更新题目发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    private void check(Question question) {
        if (XuekeEnum.fromValue(question.getType()) == null) {
            throw new BusinessException("科目类型错误");
        }
        if (TiXingEnum.fromValue(question.getQtype()) == null) {
            throw new BusinessException("题目类型错误");
        }

        if (!StringUtils.hasText(question.getTitle()) && !StringUtils.hasText(question.getPicUrl())
                && !StringUtils.hasText(question.getContent())) {
            throw new BusinessException("题干图片和内容不能全为空");
        }
    }

    /**
     * 批量删除题目（逻辑删除）
     * 使用MyBatis-Plus的逻辑删除功能，自动将is_deleted设置为1
     *
     * @param ids 题目ID列表
     * @return 操作结果
     */
    public Result<Void> deleteQuestions(List<Integer> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                throw new BusinessException("题目ID列表不能为空");
            }

            // 使用MyBatis-Plus的批量删除方法，会自动执行逻辑删除
            // 实际执行: UPDATE xy_question SET is_deleted = 1 WHERE id IN (...) AND is_deleted = 0
            boolean removed = this.removeByIds(ids);
            if (!removed) {
                throw new BusinessException("删除题目失败");
            }

            log.info("批量删除题目成功, 删除数量: {}", ids.size());
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("删除题目失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("删除题目发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 分页查询题目列表
     *
     * @param request 查询请求
     * @return 分页结果
     */
    public Result<MyPage<QuestionListData>> listQuestions(QuestionListRequest request) {
        try {
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();

            // 构建分页对象
            Page<QuestionListData> page = request.toPage();

            // 执行分页查询（使用自定义SQL关联查询创建人信息）
            Page<QuestionListData> resultPage = questionMapper.selectQuestionListWithCreator(
                    page,
                    currentUserId,
                    request.getType() == 0 ? null : request.getType(),
                    request.getQtype(),
                    request.getIfPublish(),
                    request.getKeyword()
            );

            // 转换为MyPage格式
            MyPage<QuestionListData> myPage = MyPage.fromMybatisPlusPage(resultPage);

            log.info("查询题目列表成功, 用户ID: {}, 总记录数: {}", currentUserId, myPage.getTotal());
            return Result.success(myPage);
        } catch (Exception e) {
            log.error("查询题目列表发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 根据ID列表查询题目
     * MyBatis-Plus的逻辑删除会自动过滤is_deleted=1的数据
     *
     * @param idsStr 逗号分隔的ID字符串
     * @return 题目列表
     */
    public Result<List<Question>> getQuestionsByIds(String idsStr) {
        try {
            // 处理空字符串
            if (!StringUtils.hasText(idsStr)) {
                return Result.success(new ArrayList<>());
            }

            // 去除末尾逗号
            String cleanIds = idsStr.trim();
            if (cleanIds.endsWith(",")) {
                cleanIds = cleanIds.substring(0, cleanIds.length() - 1);
            }

            // 解析ID列表
            List<Integer> ids = Arrays.stream(cleanIds.split(","))
                    .filter(StringUtils::hasText)
                    .map(String::trim)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());

            if (ids.isEmpty()) {
                return Result.success(new ArrayList<>());
            }

            // 批量查询，MyBatis-Plus会自动添加 WHERE is_deleted = 0 条件
            // 实际执行: SELECT * FROM xy_question WHERE id IN (...) AND is_deleted = 0
            List<Question> questions = this.listByIds(ids);

            log.info("根据ID列表查询题目成功, 查询数量: {}", questions.size());
            return Result.success(questions);
        } catch (NumberFormatException e) {
            log.error("ID格式错误: {}", idsStr);
            throw new BusinessException("ID格式错误");
        } catch (Exception e) {
            log.error("根据ID列表查询题目发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 查询题目详情
     * MyBatis-Plus的逻辑删除会自动过滤is_deleted=1的数据
     *
     * @param id 题目ID
     * @return 题目详情
     */
    public Result<Question> getQuestionInfo(Integer id) {
        try {
            // MyBatis-Plus会自动添加 WHERE is_deleted = 0 条件
            // 实际执行: SELECT * FROM xy_question WHERE id = #{id} AND is_deleted = 0
            Question question = this.getById(id);
            if (question == null) {
                throw new BusinessException("题目不存在");
            }

            log.info("查询题目详情成功, ID: {}", id);
            return Result.success(question);
        } catch (BusinessException e) {
            log.error("查询题目详情失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("查询题目详情发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 发布/取消发布题目
     * MyBatis-Plus的逻辑删除会自动过滤和保护已删除的数据
     *
     * @param ids   题目ID
     * @param flag 发布标志：0取消发布 1发布
     * @return 操作结果
     */
    public Result<Void> publishQuestion(List<Integer> ids, Integer flag) {
        try {
            if (CollectionUtils.isEmpty(ids)) {
                throw new BusinessException("题目ID不能为空");
            }

            // 使用 UpdateWrapper 来更新，支持设置 null 值
            LambdaUpdateWrapper<Question> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(Question::getId, ids)
                        .set(Question::getIfPublish, flag);

            // 如果是发布操作，设置发布时间
            if (flag == 1) {
                updateWrapper.set(Question::getPublishAt, System.currentTimeMillis() / 1000); // 秒级时间戳
            } else {
                // 取消发布，清空发布时间（显式设置为 null）
                updateWrapper.set(Question::getPublishAt, null);
            }

            // 执行更新（只会更新未删除的数据）
            boolean updated = this.update(updateWrapper);
            if (!updated) {
                throw new BusinessException("发布操作失败");
            }

            String operation = flag == 1 ? "发布" : "取消发布";
            log.info("{}题目成功, ID: {}", operation, ids);
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("发布操作失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("发布操作发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    public Result<List<Integer>> random(QuestionRandomRequest request) {
        try {
            // 参数校验
            if (request.getSize() == null || request.getSize() <= 0) {
                throw new BusinessException("随机数量必须大于0");
            }
            
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();
            
            // 限制最大随机数量，防止性能问题
            int maxSize = 100;
            int actualSize = Math.min(request.getSize(), maxSize);
            
            // 调用Mapper方法获取随机题目ID列表
            List<Integer> randomIds = questionMapper.selectRandomQuestionIds(
                    actualSize,
                    currentUserId,
                    request.getType(),
                    request.getQtype(),
                    request.getIfPublish(),
                    request.getDifficulty()
            );
            
            log.info("随机获取题目ID成功, 请求数量: {}, 实际返回数量: {}", request.getSize(), randomIds.size());
            return Result.success(randomIds);
        } catch (BusinessException e) {
            log.error("随机获取题目失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("随机获取题目发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }
}
